package com.youku.component;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.junit.Assert;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.youku.expression.Expression;
import com.youku.expression.Position;
import com.youku.util.Consts;

/**
 * 等待/睡眠
 * 
 * ms 毫秒 s 秒 m 分钟 h 小时 d 天
 * 
 * 如下例表示等待1分钟 <sleep time="1m"/>
 * 
 * @author loda
 *
 */
public class SleepTimer implements CaseStep, SuiteStep, ProjectStep {

	private Expression time;

	private static final Logger logger = LoggerFactory.getLogger(SleepTimer.class);

	private static final Map<String, Integer> units;

	/**
	 * 
	 * @param projectId
	 *            项目id
	 * @param timeString
	 *            停顿时间
	 */
	public SleepTimer(Position position, String timeString) {
		super();
		this.time = new Expression(position, timeString);
	}

	public SleepTimer() {
	}

	static {
		units = new HashMap<>();

		units.put("ms", 1);
		units.put("s", 1000);
		units.put("m", 1000 * 60);
		units.put("h", 1000 * 60 * 60);
		units.put("d", 1000 * 60 * 60 * 24);
	}

	@Override
	public void run() {
		String s = time.get();
		Assert.assertFalse("暂停时间不能为空，错误信息在" + time.position(), StringUtils.isBlank(s));
		int index = stopInFirstNonnumeric(s);

		String unitString = Consts.DEFAULT_UNIT;

		String numberString = s;

		if (index == 0) {
			throw new RuntimeException("暂停时间不能为空，错误信息在" + time.position());
		}

		if (index != -1) {
			unitString = s.substring(index);
			numberString = s.substring(0, index);
		}

		if (!units.containsKey(unitString)) {
			throw new RuntimeException("单位填写错误，不存在该单位：" + unitString + "，错误发生在" + time.position());
		}

		double number = Double.parseDouble(numberString);

		Assert.assertTrue("暂停时间不得负数，错误发生在" + time.position(), number >= 0);

		try {
			logger.info("========================开始等待" + number + unitString);
			Thread.sleep(Math.round(number * units.get(unitString)));
		} catch (InterruptedException e) {
			throw new Error(e);
		}
	}

	private int stopInFirstNonnumeric(String s) {
		for (int i = 0; i < s.length(); i++) {
			char ch = s.charAt(i);
			if (ch < '0' || ch > '9') {
				return i;
			}
		}
		return -1;
	}

	@Override
	public String getKey() {
		return null;
	}

	@Override
	public void updatePosition(Position position) {
		time.setPosition(position);
	}

	@Override
	public void setScope(BaseAttribute attribute) {
		// TODO sleep的作用域，无须填写，无意义
	}

	@Override
	public CaseStep cloneStep() {
		SleepTimer timer = new SleepTimer();
		timer.time = new Expression(time.getPosition(), time.getExpressionString());
		return timer;
	}

}
